package cn.edu.xmu.orderpayment.payment.Dao;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.orderpayment.payment.mapper.PaymentPatternPoMapper;
import cn.edu.xmu.orderpayment.payment.mapper.PaymentPoMapper;
import cn.edu.xmu.orderpayment.payment.mapper.RefundPoMapper;
import cn.edu.xmu.orderpayment.payment.model.bo.PaymentPattern;
import cn.edu.xmu.orderpayment.payment.model.bo.Refund;
import cn.edu.xmu.orderpayment.payment.model.po.*;
import cn.edu.xmu.orderpayment.payment.model.vo.SimpleRefundRetVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.setPoModifiedFields;

/**
 * @author  Gaunlin Wang 22920192204282
 * @date  2021-11-15
 */
@Repository
public class RefundDao {

    @Autowired(required = false)
    private RefundPoMapper refundPoMapper;

    @Autowired(required = false)
    private PaymentPoMapper paymentPoMapper;

    private static final Logger logger = LoggerFactory.getLogger(RefundDao.class);

    @Autowired(required = false)
    private PaymentPatternPoMapper paymentPatternPoMapper;

    /**
     * 平台管理员通过id查询退款详细信息
     * 查询条件：单据ID
     * 利用Mapper的selectByPrimaryKey
     * @return Refund
     */
    public ReturnObject getRefundDetailInfo(Long id) {
        try {
            RefundPo refundPo = refundPoMapper.selectByPrimaryKey(id);
            if (refundPo == null) {
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "退款信息不存在");
            }
            Refund refund = cloneVo(refundPo, Refund.class);
            return new ReturnObject(refund);
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public ReturnObject<List> getPaymentByExample(PaymentPoExample paymentPoExample) {
        try {
            List<PaymentPo> list = paymentPoMapper.selectByExample(paymentPoExample);
            if (list.size() == 0) {
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "支付信息不存在");
            }
            return new ReturnObject(list);
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

//    /**
//     * 创建退款单
//     * @param refund
//     * @return
//     */
//    public ReturnObject<Refund> createRefund(Refund refund) {
//        try{
//            RefundPo refundPo=cloneVo(refund,RefundPo.class);
//            refundPoMapper.insert(refundPo);
//            return new ReturnObject<>(cloneVo(refundPo,Refund.class));
//
//        }catch (Exception e){
//            logger.error(e.getMessage());
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
//        }
//    }

    //通过退款id查询详细信息
    public ReturnObject selectRefundInfoByPrimaryKey(Long id){
        try{
            RefundPo po = refundPoMapper.selectByPrimaryKey(id);
            var ret = new ReturnObject(po);
            return Common.getRetVo(ret, Refund.class);
        }catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    //更新信息, 对数据库进行操作
    public ReturnObject updateRefund(Refund bo, Long loginUserId, String loginUserName) {
        try{
            RefundPo po = refundPoMapper.selectByPrimaryKey(bo.getId());//通过id创建Refund的PO对象
            if(po == null){
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "退款id不存在");
            }
            Refund retBo = (Refund)cloneVo(po, Refund.class);// 模型转换
            ///只有未对账的状态才能修改，用于手工挂账处理，否则出507错误
//            if(po.getState().equals(Refund.State.RECONCILIATION_COMPLETED.getCode()) || po.getState().equals(Refund.State.LIQUIDATION_COMPLETED.getCode()))
//                return new ReturnObject(ReturnNo.STATENOTALLOW, "当前状态禁止此操作");
            ///Dao层进行测试 -> 过滤掉不符合 未对账 状态的
            po.setState(bo.getState().getCode());// 校验无误后设置状态
            if(bo.getDescr() != null)
                po.setDescr(bo.getDescr());
            //根据传入的body修改信息
            setPoModifiedFields(po, loginUserId, loginUserName);
            refundPoMapper.updateByPrimaryKeySelective(po);//通过
            return new ReturnObject(retBo);
        }catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

//    /**
//     * 获取某个时间段内的退款单
//     * @param beginTime
//     * @param endTime
//     * @return
//     */
//    public ReturnObject getRefundsByTime(ZonedDateTime beginTime, ZonedDateTime endTime){
//        try {
//            RefundPoExample refundPoExample = new RefundPoExample();
//            RefundPoExample.Criteria criteria = refundPoExample.createCriteria();
//            if (beginTime != null) {
//                criteria.andRefundTimeGreaterThanOrEqualTo(beginTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
//            }
//            if (endTime != null) {
//                criteria.andRefundTimeLessThanOrEqualTo(endTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
//            }
//            List<RefundPo> refundPos = refundPoMapper.selectByExample(refundPoExample);
//            List<Refund> refunds = new ArrayList<>(refundPos.size());
//            for(RefundPo refundPo:refundPos){
//                refunds.add(cloneVo(refundPo,Refund.class));
//            }
//            return new ReturnObject(refunds);
//        }catch (Exception e){
//            logger.error(e.getMessage());
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
//        }
//    }

    /**
     * 平台管理员查询退款信息
     * 查询条件：单据ID，状态，晚于此退款时间，早于此退款时间，页码，页数
     * 不返回已被逻辑删除的退款信息，按照时间倒序
     *
     * 利用Mapper的select和PoExample配合
     * @return Array(SimpleRefund)
     */
    public ReturnObject getRefundInfo(RefundPoExample example,Integer page,Integer pageSize) {

        try {
            PageHelper.startPage(page, pageSize);
            List<RefundPo> poList = refundPoMapper.selectByExample(example);
            List<SimpleRefundRetVo> voList = new ArrayList<>();
            for (RefundPo refundPo : poList) {
                voList.add( cloneVo(refundPo,SimpleRefundRetVo.class));
            }

            PageInfo pageInfo = PageInfo.of(poList);
            pageInfo.setList(voList);
            return new ReturnObject(pageInfo);

        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    /**
     * 平台管理员修改退款单信息
     * @return
     */
//    public ReturnObject modifyRefundInfo(Refund refundBo, Long loginId, String loginName) {
//        try {
//            RefundPo refundPo = cloneVo(refundBo, RefundPo.class);
//            setPoModifiedFields(refundPo, loginId, loginName);
//            refundPoMapper.updateByPrimaryKeySelective(refundPo);
//            return new ReturnObject(refundPoMapper.selectByPrimaryKey(refundPo.getId()));
//        } catch (Exception e) {
//            logger.error("PayDao.modifyRefundInfo:" + e.getMessage());
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
//        }
//    }

    /**
     * 通过documentId获取退款单
     * @param documentId
     * @return
     */
    public ReturnObject<List<RefundPo>> getRefundByDocumentId(String documentId) {
        try {
            RefundPoExample example = new RefundPoExample();
            RefundPoExample.Criteria criteria = example.createCriteria();
            criteria.andDocumentIdEqualTo(documentId);
            List<RefundPo> list = refundPoMapper.selectByExample(example);
            if (list.size() == 0) {
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST, "退款信息不存在");
            }
            return new ReturnObject(list);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

//    /**
//     * 通过支付渠道id获得支付信息用于退款内部api
//     * @param patternId
//     * @return
//     */
//    public ReturnObject getPaymentPatternById(Long patternId) {
//        try{
//            PaymentPatternPo po=paymentPatternPoMapper.selectByPrimaryKey(patternId);
//            if(po==null)return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST,"该支付方式不存在");
//            return new ReturnObject<>(cloneVo(po, PaymentPattern.class));
//        }
//        catch (Exception e){
//            logger.error(e.getMessage());
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
//        }
//    }

//    /**
//     * 修改退款单为已对账
//     * @param refund
//     * @return
//     * @author wang xusheng
//     */
//    public ReturnObject setRefundReconciled(Refund refund){
//        try{
//            RefundPo refundPo = cloneVo(refund, RefundPo.class);
//            refundPoMapper.updateByPrimaryKeySelective(refundPo);
//            return new ReturnObject(ReturnNo.OK);
//        }catch (Exception e){
//            logger.error(e.getMessage());
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR,e.getMessage());
//        }
//    }

    /**
     * 获取退款单所有状态
     * @param[]
     * @return RefundPo
     */
    public ReturnObject getRefundStates(){
        List<Map<String,Object>> stateList = new ArrayList<>();
        for(Refund.State state : Refund.State.values()){
            Map<String, Object> temp = new HashMap<>(); // temp暂时存储code-name
            temp.put("code", state.getCode()); // 返回状态码
            temp.put("name", state.getDescription()); // 返回状态名
            stateList.add(temp);
        }
        return new ReturnObject<>(stateList);
    }

}
